﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace DS_Server
{
    public interface IDS
    {
        void Create(Person person);
        pList Read();
        void Update(int id, string fname, string lname, int age);
        void Delete(int id);

        IDS isReady(string path);

        IDS Next
        { get; set; }

        string path
        { get; set; }
    }

    public class DS_CSV : IDS
    {
        string _path;

        public string path
        {
            get { return _path; }
            set { _path = value; }
        }
        public IDS isReady(string path)
        {
            this.path = path;
            string[] strArray = path.Split('.');
            string extension = strArray[strArray.Length - 1];
            IDS ret = null;
            if (extension == "csv")
            {
                ret = this;
            }
            else if (Next != null)
            {
                ret = Next.isReady(path);
            }
            return ret;
        }

        private IDS next;

        public IDS Next
        {
            get { return next; }
            set { next = value; }
        }

        public void Create(Person person)
        {
            using (System.IO.StreamWriter file = new System.IO.StreamWriter(path, true))
            {
                file.WriteLine(person.SaveToSCV());
            }
        }

        public pList Read()
        {
            pList x = new pList();
            using (System.IO.StreamReader file = new System.IO.StreamReader(path))
            {
                string str;
                while ((str = file.ReadLine()) != null)
                {
                    string[] strArray = str.Split(';');
                    Person t = new Person();
                    t.LoadFromCSV(strArray);
                    x.Add(t);
                }
            }
            return x;
        }
        public void Update(int id, string fname, string lname, int age)
        {
            using (System.IO.StreamReader reader = new System.IO.StreamReader(path))
            {
                using (System.IO.StreamWriter writer = new System.IO.StreamWriter("UpdateHandle.csv"))
                {
                    string str;
                    while ((str = reader.ReadLine()) != null)
                    {
                        string[] strArray = str.Split(';');
                        if (strArray[1] == id.ToString())
                        {
                            string tmp = "MySerialization.Person;" + id.ToString() + ";" + fname.ToString() + ";"
                                            + lname.ToString() + ";" + age.ToString();
                            writer.WriteLine(tmp);
                        }
                        else
                        {
                            writer.WriteLine(str);
                        }
                    }
                }
            }

            File.Replace("UpdateHandle.csv", path, "UpdateHandle_backUp.csv");
        }

        public void Delete(int id)
        {
            using (System.IO.StreamReader reader = new System.IO.StreamReader(path))
            {
                using (System.IO.StreamWriter writer = new System.IO.StreamWriter("UpdateHandle.csv"))
                {
                    string str;
                    while ((str = reader.ReadLine()) != null)
                    {
                        string[] strArray = str.Split(';');
                        if (strArray[1] != id.ToString())
                        {
                            writer.WriteLine(str);
                        }
                    }
                }
            }

            File.Replace("UpdateHandle.csv", path, "UpdateHandle_backUp.csv");

            //using (System.IO.StreamReader reader = new System.IO.StreamReader("UpdateHandle.csv"))
            //{
            //    using (System.IO.StreamWriter writer = new System.IO.StreamWriter(path))
            //    {
            //        string str;
            //        while ((str = reader.ReadLine()) != null)
            //        {
            //            writer.WriteLine(str);
            //        }
            //    }
            //}   
        }
    }


    public class DS_DB : IDS
    {
        string _path;

        public string path
        {
            get { return _path; }
            set { _path = value; }
        }
        public IDS isReady(string path)
        {
            this.path = path;
            string[] strArray = path.Split('.', ' ', '=');
            string extension = strArray[0] + " " + strArray[1];
            IDS ret = null;
            if (extension == "Data Source")
            {
                ret = this;
            }
            else if (Next != null)
            {
                ret = Next.isReady(path);
            }
            return ret;
        }
        private IDS next;

        public IDS Next
        {
            get { return next; }
            set { next = value; }
        }

        public void Create(Person person)
        {
            DbProviderFactory factory = SqlClientFactory.Instance;
            DbConnection conn = factory.CreateConnection();
            conn.ConnectionString = path;
            conn.Open();
            /*
            DbCommand WipeCommand = factory.CreateCommand();
            WipeCommand.CommandText = "TRUNCATE TABLE Persons";
            WipeCommand.Connection = conn;
            WipeCommand.ExecuteScalar();
            */
            DbCommand SaveCommand = factory.CreateCommand();
            SaveCommand.CommandText = "INSERT INTO Persons VALUES (@id, @FName, @LName, @Age)";
            SaveCommand.Connection = conn;

            DbParameter IdParam = factory.CreateParameter();
            IdParam.ParameterName = "@id";
            SaveCommand.Parameters.Add(IdParam);

            DbParameter FNameParam = factory.CreateParameter();
            FNameParam.ParameterName = "@FName";
            SaveCommand.Parameters.Add(FNameParam);

            DbParameter LNameParam = factory.CreateParameter();
            LNameParam.ParameterName = "@LName";
            SaveCommand.Parameters.Add(LNameParam);

            DbParameter AgeParam = factory.CreateParameter();
            AgeParam.ParameterName = "@Age";
            SaveCommand.Parameters.Add(AgeParam);

            string[] strArray = person.SaveToDB().Split(':');

            IdParam.Value = strArray[1];
            FNameParam.Value = strArray[2];
            LNameParam.Value = strArray[3];
            AgeParam.Value = strArray[4];

            SaveCommand.ExecuteScalar();
            
            conn.Close();
        }

        public pList Read()
        {
            pList x = new pList();

            DbProviderFactory factory = SqlClientFactory.Instance;
            DbConnection conn = factory.CreateConnection();
            conn.ConnectionString = path;
            conn.Open();

            DbCommand readCommand = factory.CreateCommand();
            readCommand.CommandText = "SELECT * FROM Persons";
            readCommand.Connection = conn;
            DbDataReader reader = readCommand.ExecuteReader();

            while (reader.Read())
            {
                object[] values = new object[reader.FieldCount];
                reader.GetValues(values);
                Person p = new Person();
                p.LoadFromDB(values);
                x.Add(p);
            }
            return x;
        }

        public void Update(int id, string fname, string lname, int age)
        {
            DbProviderFactory factory = SqlClientFactory.Instance;
            DbConnection conn = factory.CreateConnection();
            conn.ConnectionString = path;
            conn.Open();

            DbCommand UpdateCommand = factory.CreateCommand();
            UpdateCommand.CommandText = "UPDATE Persons SET FName = @FName, LName = @LName, Age = @Age WHERE id = @id";
            UpdateCommand.Connection = conn;

            DbParameter IdParam = factory.CreateParameter();
            IdParam.ParameterName = "@id";
            IdParam.Value = id;
            UpdateCommand.Parameters.Add(IdParam);

            DbParameter FNameParam = factory.CreateParameter();
            FNameParam.ParameterName = "@FName";
            FNameParam.Value = fname;
            UpdateCommand.Parameters.Add(FNameParam);

            DbParameter LNameParam = factory.CreateParameter();
            LNameParam.ParameterName = "@LName";
            LNameParam.Value = lname;
            UpdateCommand.Parameters.Add(LNameParam);

            DbParameter AgeParam = factory.CreateParameter();
            AgeParam.ParameterName = "@Age";
            AgeParam.Value = age;
            UpdateCommand.Parameters.Add(AgeParam);

            UpdateCommand.ExecuteScalar();
        }

        public void Delete(int id)
        {
            DbProviderFactory factory = SqlClientFactory.Instance;
            DbConnection conn = factory.CreateConnection();
            conn.ConnectionString = path;
            conn.Open();

            DbCommand DeleteCommand = factory.CreateCommand();
            DeleteCommand.CommandText = "DELETE FROM Persons WHERE id = @id";
            DeleteCommand.Connection = conn;

            DbParameter IdParam = factory.CreateParameter();
            IdParam.ParameterName = "@id";
            IdParam.Value = id;
            DeleteCommand.Parameters.Add(IdParam);

            DeleteCommand.ExecuteScalar();
        }
    }
}
